<?php
/***********************************/
// World of Warcraft Armory SDK    //
// Licence: GNU GPLv3              //
// Author: Giacomo 'elegos' Furlan //
// File: wowasdk.character.php     //
/***********************************/

/**
  This class allows you to browse
  your character's general
  data from the Armory.
*/
class wowasdk_character {
	private $xmlsheet;
	private $region;
	private $char_url;
	
	/**
	  Constructor of the class.
	  @param $region EU or US
	  @param $server The server's name
	  @param $cname The character's name
	  @param $force_cache TRUE: new data will be downloaded; FALSE: new data will be downloaded only if the cache one is outdated (3 days)
	*/
	function __construct($region,$server,$cname, $force_cache = false) {
		$server = explode(" ",$server);
		for($i = 0; $i < count($server); $i++)
			$server[$i] = ucfirst(strtolower($server[$i]));
		$server = implode(" ",$server);
		$server_plus = str_replace(" ","+",$server);
		
		$fileurl = "characters/$region/$server/$cname/main.xml";
		
		$this->region = $region;
		
		@mkdir("characters/$region/$server/$cname",0777,true);

		switch($region) {
			case EU:
				$this->char_url = "http://eu.wowarmory.com/character-sheet.xml?";
				break;
			case US:
				$this->char_url = "http://www.wowarmory.com/character-sheet.xml?";
				break;
			default:
				die("No valid region selected.\n");
		}
		
		$r_string = $this->char_url."r=$server_plus&cn=$cname";
		downloadFileViaCurl($r_string,$fileurl,259200,$force_cache);

		$this->xmlsheet = simplexml_load_file($fileurl);
	}
	
	/**
	  (String) Battle Group's name.
	*/
	function getBattleGroup() {
		return $this->xmlsheet->characterInfo->character["battleGroup"];
	}
	
	/**
	  (String) Armory's URL of the character.
	*/
	function getCharUrl() {
		return $this->char_url.$this->xmlsheet->characterInfo->character["charUrl"];
	}
	
	/**
	  (String) Name.
	*/
	function getName() {
		return utf8_decode($this->xmlsheet->characterInfo->character["name"]);
	}
	
	/**
	  (String) Name prefix.
	*/
	function getNamePrefix() {
		return $this->xmlsheet->characterInfo->character["prefix"];
	}
	
	/**
	  (String) Name suffix.
	*/
	function getNameSuffix() {
		return $this->xmlsheet->characterInfo->character["suffix"];
	}
	
	/**
	  (String) Class.
	*/
	function getClass() {
		return $this->xmlsheet->characterInfo->character["class"];
	}
	
	/**
	  (Integer) Class' ID.
	*/
	function getClassId() {
		return $this->xmlsheet->characterInfo->character["classId"];
	}
	
	/**
	  (String) Faction.
	*/
	function getFaction() {
		return $this->xmlsheet->characterInfo->character["faction"];
	}
	
	/**
	  (Integer) Faction's ID.
	*/
	function getFactionId() {
		return $this->xmlsheet->characterInfo->character["factionId"];
	}
	
	/**
	  (String) Gender.
	*/
	function getGender() {
		return $this->xmlsheet->characterInfo->character["gender"];
	}
	
	/**
	  (Integer) Gender's ID.
	*/
	function getGenderId() {
		return $this->xmlsheet->characterInfo->character["genderId"];
	}
	
	/**
	  (String) Guild name.
	*/
	function getGuildName() {
		return $this->xmlsheet->characterInfo->character["guildName"];
	}
	
	/**
	  (String) Armory's guild's URL.
	*/
	function getGuildUrl() {
		return $this->char_url.$this->xmlsheet->characterInfo->character["guildUrl"];
	}
	
	/**
	  (String) Last modified time stamp (dd Month yyyy).
	*/
	function getLastModified() {
		return $this->xmlsheet->characterInfo->character["lastModified"];
	}
	
	/**
	  (Integer) Level.
	*/
	function getLevel() {
		return $this->xmlsheet->characterInfo->character["level"];
	}
	
	/**
	  (String) Achievement total points.
	*/
	function getAchievementPoints() {
		return $this->xmlsheet->characterInfo->character["points"];
	}
	
	/**
	  (String) Race.
	*/
	function getRace() {
		return $this->xmlsheet->characterInfo->character["race"];
	}
	
	/**
	  (Integer) Race's ID.
	*/
	function getRaceId() {
		return $this->xmlsheet->characterInfo->character["raceId"];
	}
	
	/**
	  (String) Realm name.
	*/
	function getRealm() {
		return $this->xmlsheet->characterInfo->character["realm"];
	}
	
	/**
	  (Array) Primary spec, returns if it's the active spec, the main spec and the number of talent points used in each tree.
	  (Bool) isActive, (String) mainTree, (Integer) treeOne, (Integer) treeTwo, (Integer) treeThree
	*/
	function getPrimarySpec() {
		foreach($this->xmlsheet->characterInfo->characterTab->talentSpecs->talentSpec as $specs => $data) {
			if($data['group'] == 1) {
				$return = array (
						"isActive" => $data['active'],
						"mainTree" => $data['prim'],
						"treeOne" => $data['treeOne'],
						"treeTwo" => $data['treeTwo'],
						"treeThree" => $data['treeThree']
					);
			}
		}
		if($return['isActive'] == "") $return['isActive'] = false;
		else $return['isActive'] = true;
		return $return;
	}
	
	/**
	  (Array) Secondary spec, returns NULL if there is no secondary spec.
	  @see wowasdk_character::getPrimarySpec
	*/
	function getSecondarySpec() {
		foreach($this->xmlsheet->characterInfo->characterTab->talentSpecs->talentSpec as $specs => $data) {
			if($data['group'] == 1) continue;
			$return = array (
					"isActive" => $data['active'],
					"mainTree" => $data['prim'],
					"treeOne" => $data['treeOne'],
					"treeTwo" => $data['treeTwo'],
					"treeThree" => $data['treeThree']
				);
		}
		if(isset($return)) {
			if($return['isActive'] == "") $return['isActive'] = false;
			else $return['isActive'] = true;
		}
		return $return;
	}
	
	/**
	  (Array) Active spec, returns the main spec and the number of talent points used in each tree.
	  (String) mainTree, (Integer) treeOne, (Integer) treeTwo, (Integer) treeThree
	*/
	function getActiveSpec() {
		foreach($this->xmlsheet->characterInfo->characterTab->talentSpecs->talentSpec as $specs => $data) {
			if($data['active'] != 1) continue;
			$return = array (
					"mainTree" => $data['prim'],
					"treeOne" => $data['treeOne'],
					"treeTwo" => $data['treeTwo'],
					"treeThree" => $data['treeThree']
				);
		}
		return $return;
	}
	
	/**
	  (Integer) Life-time honorable kills.
	*/
	function getLifetimeHonorableKills() {
		return $this->xmlsheet->characterInfo->characterTab->pvp->lifetimehonorablekills['value'];
	}
	
	/**
	  (Array) Primary profesions: return[0/1] => ["name" (String)] = profession name, ["skill" (Integer)] skill value.
	*/
	function getProfessions() {
		$i = 0;
		foreach($this->xmlsheet->characterInfo->characterTab->professions->skill as $skill => $data) {
			$return[$i] = array(
				"name" => $data["name"],
				"skill" => $data["value"]
			);
		}
	}
	
	/**
	  (Integer) Maximum health.
	*/
	function getMaxHealth() {
		return $this->xmlsheet->characterInfo->characterTab->characterBars->health["effective"];
	}
	
	/**
	  (Array) The second bar (mana, rage, runic): return["type"] = SECONDBAR_TYPE_*, return["maxValue"] = maximum value of the second bar.
	*/
	function getSecondBar() {
		return array(
			"type" => $this->xmlsheet->characterInfo->characterTab->characterBars->secondBar["type"],
			"maxValue" => $this->xmlsheet->characterInfo->characterTab->characterBars->secondBar["effective"]
		);
	}
	
	/**
	  (Integer) Effective base statistic value, returns null if $stat is not valid.
	  @param $stat BASESTAT_*
	*/
	function getBaseStat($stat) {
		switch($stat) {
			case BASESTAT_STRENGHT:
				return $this->xmlsheet->characterInfo->characterTab->baseStats->strenght["effective"];
			case BASESTAT_AGILITY:
				return $this->xmlsheet->characterInfo->characterTab->baseStats->agility["effective"];
			case BASESTAT_STAMINA:
				return $this->xmlsheet->characterInfo->characterTab->baseStats->stamina["effective"];
			case BASESTAT_INTELLECT:
				return $this->xmlsheet->characterInfo->characterTab->baseStats->intellect["effective"];
			case BASESTAT_SPIRIT:
				return $this->xmlsheet->characterInfo->characterTab->baseStats->spirit["effective"];
			case BASESTAT_ARMOR:
				return $this->xmlsheet->characterInfo->characterTab->baseStats->armor["effective"];
			default:
				return NULL;
		}
		return NULL;
	}
	
	/**
	  (Integer) Resistance to element, returns null if $element is not valid.
	  @param $element RESISTANCE_*
	*/
	function getResistance($element) {
		switch($element) {
			case RESISTANCE_ARCANE:
				return $this->xmlsheet->characterInfo->characterTab->resistances->arcane["value"];
			case RESISTANCE_FIRE:
				return $this->xmlsheet->characterInfo->characterTab->resistances->fire["value"];
			case RESISTANCE_FROST:
				return $this->xmlsheet->characterInfo->characterTab->resistances->frost["value"];
			case RESISTANCE_HOLY:
				return $this->xmlsheet->characterInfo->characterTab->resistances->holy["value"];
			case RESISTANCE_NATURE:
				return $this->xmlsheet->characterInfo->characterTab->resistances->nature["value"];
			case RESISTANCE_SHADOW:
				return $this->xmlsheet->characterInfo->characterTab->resistances->shadow["value"];
		}
		return NULL;
	}
	
	/**
	  (Array) Main hand damage stats.
	  Return -> ["dps"], ["max"], ["min"], ["percent"], ["speed"].
	*/
	function getMainHandDamage() {
		return array(
			"dps" => $this->xmlsheet->characterInfo->characterTab->melee->mainHandDamage["dps"],
			"max" => $this->xmlsheet->characterInfo->characterTab->melee->mainHandDamage["max"],
			"min" => $this->xmlsheet->characterInfo->characterTab->melee->mainHandDamage["min"],
			"percent" => $this->xmlsheet->characterInfo->characterTab->melee->mainHandDamage["percent"],
			"speed" => $this->xmlsheet->characterInfo->characterTab->melee->mainHandDamage["speed"]
		);
	}
	
	/**
	  (Array) Main hand speed stats.
	  Return -> ["hastePercent"], ["hasteRating"], ["speed"] (seconds/hit).
	*/
	function getMainHandSpeed() {
		return array(
			"hastePercent" => $this->xmlsheet->characterInfo->characterTab->melee->mainHandSpeed["hastePercent"],
			"hasteRating" => $this->xmlsheet->characterInfo->characterTab->melee->mainHandSpeed["hasteRating"],
			"speed" => $this->xmlsheet->characterInfo->characterTab->melee->mainHandSpeed["speed"]

		);
	}
	
	/**
	  (Array) Off hand damage stats.
	  @see wowasdk_character::getMainHandDamage
	*/
	function getOffHandDamage() {
		return array(
			"dps" => $this->xmlsheet->characterInfo->characterTab->melee->offHandDamage["dps"],
			"max" => $this->xmlsheet->characterInfo->characterTab->melee->offHandDamage["max"],
			"min" => $this->xmlsheet->characterInfo->characterTab->melee->offHandDamage["min"],
			"percent" => $this->xmlsheet->characterInfo->characterTab->melee->offHandDamage["percent"],
			"speed" => $this->xmlsheet->characterInfo->characterTab->melee->offHandDamage["speed"]
		);
	}
	
	/**
	  (Array) Off hand speed stats.
	  @see wowasdk_character::getMainHandSpeed
	*/
	function getOffHandSpeed() {
		return array(
			"hastePercent" => $this->xmlsheet->characterInfo->characterTab->melee->offHandSpeed["hastePercent"],
			"hasteRating" => $this->xmlsheet->characterInfo->characterTab->melee->offHandSpeed["hasteRating"],
			"speed" => $this->xmlsheet->characterInfo->characterTab->melee->offHandSpeed["speed"]

		);
	}
	
	/**
	  (Array) Melee power stats.
	  Return -> ["base"] (base value), ["effective"] (objects-empowered value), ["increasedDps"] (increased DPS).
	*/
	function getMeleePower() {
		return array(
			"base" => $this->xmlsheet->characterInfo->characterTab->melee->power["base"],
			"effective" => $this->xmlsheet->characterInfo->characterTab->melee->power["effective"],
			"increasedDps" => $this->xmlsheet->characterInfo->characterTab->melee->power["increasedDps"]
		);
	}
	
	/**
	  (Array) Melee hit rating stats.
	  Return -> ["percent"], ["penetration"] (increased armor penetration), ["armorPercent"] (armor penetration bonus percent), ["value"].
	*/
	function getMeleeHitRating() {
		return array(
			"percent" => $this->xmlsheet->characterInfo->characterTab->melee->hitRating["increasedHitPercent"],
			"penetration" => $this->xmlsheet->characterInfo->characterTab->melee->hitRating["penetration"],
			"armorPercent" => $this->xmlsheet->characterInfo->characterTab->melee->hitRating["reducedArmorPercent"],
			"value" => $this->xmlsheet->characterInfo->characterTab->melee->hitRating["value"]
		);
	}
	
	/**
		(Array) Melee critic hit chance stats.
		Return -> ["percent"] (base stat percent), ["plusPercent"] (objects-based percent bonus), ["rating"] (raw number).
	*/
	function getMeleeCritChance() {
		return array(
			"percent" => $this->xmlsheet->characterInfo->characterTab->melee->critChance["percent"],
			"plusPercent" => $this->xmlsheet->characterInfo->characterTab->melee->critChance["plusPercent"],
			"rating" => $this->xmlsheet->characterInfo->characterTab->melee->critChance["rating"]
		);
	}
	
	/**
		(Array) Expertise stats.
		Return -> ["additional"], ["percent"], ["rating"], ["value"].
	*/
	function getExpertise() {
		return array(
			"additional" => $this->xmlsheet->characterInfo->characterTab->melee->expertise["additional"],
			"percent" => $this->xmlsheet->characterInfo->characterTab->melee->expertise["percent"],
			"rating" => $this->xmlsheet->characterInfo->characterTab->melee->expertise["rating"],
			"value" => $this->xmlsheet->characterInfo->characterTab->melee->expertise["value"]
		);
	}
	
	/**
		(Array) Ranged weapon skill stats (equipped).
		Return -> ["rating"], ["value"].
	*/
	function getRangedWeaponSkill() {
		return array(
			"rating" => $this->xmlsheet->characterInfo->characterTab->ranged->weaponSkill["rating"],
			"value" => $this->xmlsheet->characterInfo->characterTab->ranged->weaponSkill["value"]
		);
	}
	
	/**
		(Array) Ranged damage stats (equipped).
		Return -> ["dps"], ["max"], ["min"], ["percent"], ["speed"].
	*/
	function getRangedDamage() {
		return array(
			"dps" => $this->xmlsheet->characterInfo->characterTab->ranged->damage["dps"],
			"max" => $this->xmlsheet->characterInfo->characterTab->ranged->damage["max"],
			"min" => $this->xmlsheet->characterInfo->characterTab->ranged->damage["min"],
			"percent" => $this->xmlsheet->characterInfo->characterTab->ranged->damage["percent"],
			"speed" => $this->xmlsheet->characterInfo->characterTab->ranged->damage["speed"]
		);
	}
	
	/**
		(Array) Ranged power stats.
		Return -> ["base"], ["effective"], ["increasedDps"], ["petAttack"], ["petSpell"].
	*/
	function getRangedPower() {
		return array(
			"base" => $this->xmlsheet->characterInfo->characterTab->ranged->power["base"],
			"effective" => $this->xmlsheet->characterInfo->characterTab->ranged->power["effective"],
			"increasedDps" => $this->xmlsheet->characterInfo->characterTab->ranged->power["increasedDps"],
			"petAttack" => $this->xmlsheet->characterInfo->characterTab->ranged->power["petAttack"],
			"petSpell" => $this->xmlsheet->characterInfo->characterTab->ranged->power["petSpell"]
		);
	}
	
	/**
		(Array) Ranged hit rating stats.
		Return -> ["increasedHitRatingPercent"], ["penetration"], ["reducedArmorPercent"], ["value"].
	*/
	function getRangedHitRating() {
		return array(
			"increasedHitRatingPercent" => $this->xmlsheet->characterInfo->characterTab->ranged->hitRating["increasedHitRatingPercent"],
			"penetration" => $this->xmlsheet->characterInfo->characterTab->ranged->hitRating["penetration"],
			"reducedArmorPercent" => $this->xmlsheet->characterInfo->characterTab->ranged->hitRating["reducedArmorPercent"],
			"value" => $this->xmlsheet->characterInfo->characterTab->ranged->hitRating["value"]
		);
	}
	
	/**
		(Array) Ranged critical chance stats.
		Return -> ["percent"], ["plusPercent"], ["rating"].
	*/
	function getRangedCriticalChance() {
		return array(
			"percent" => $this->xmlsheet->characterInfo->characterTab->ranged->critChange["percent"],
			"plusPercent" => $this->xmlsheet->characterInfo->characterTab->ranged->critChance["plusPercent"],
			"rating" => $this->xmlsheet->characterInfo->characterTab->ranged->critChance["rating"]
		);
	}
	
	/**
		(Integer) Spell bonus damage (by element).
		Returns -1 if SPELL_TYPE_ is not recognised.
		@param $type SPELL_TYPE_*
	*/
	function getSpellBonusDamage($type) {
		switch($type)
		{
			case SPELL_TYPE_ARCANE:
				return  $this->xmlsheet->characterInfo->characterTab->spell->bonusDamage->arcane["value"];
			case SPELL_TYPE_FIRE:
				return  $this->xmlsheet->characterInfo->characterTab->spell->bonusDamage->fire["value"];
			case SPELL_TYPE_FROST:
				return  $this->xmlsheet->characterInfo->characterTab->spell->bonusDamage->frost["value"];
			case SPELL_TYPE_HOLY:
				return  $this->xmlsheet->characterInfo->characterTab->spell->bonusDamage->holy["value"];
			case SPELL_TYPE_NATURE:
				return  $this->xmlsheet->characterInfo->characterTab->spell->bonusDamage->nature["value"];
			case SPELL_TYPE_SHADOW:
				return  $this->xmlsheet->characterInfo->characterTab->spell->bonusDamage->shadow["value"];
			case SPELL_TYPE_PET_BONUS:
				return  $this->xmlsheet->characterInfo->characterTab->spell->bonusDamage->petBonus["value"];			default:
				return -1;
		}
	}
	
	/**
		(Integer) Spell bonus healing.
	*/
	function getSpellBonusHealing() {
		return $this->xmlsheet->characterInfo->characterTab->spell->bonusHealing["value"];
	}
	
	/**
		(Array) Spell hit rating stats.
		Return -> ["increasedHitRating"], ["penetration"], ["reducedResist"], ["value"].
	*/
	function getSpellHitRating() {
		return array(
			"increasedHitRating" => $this->xmlsheet->characterInfo->characterTab->spell->hitRating["increasedHitRating"],
			"penetration" => $this->xmlsheet->characterInfo->characterTab->spell->hitRating["penetration"],
			"reducedResist" => $this->xmlsheet->characterInfo->characterTab->spell->hitRating["reducedResist"],
			"value" => $this->xmlsheet->characterInfo->characterTab->spell->hitRating["value"]
		);
	}
	
	/**
		(Integer) Spell critical chance rating.
	*/
	function getSpellCriticalChanceRating() {
		return $this->xmlsheet->characterInfo->characterTab->spell->critChance["rating"];
	}
	
	/**
		(Integer) Spell critical chance percent (by element).
		Returns -1 if SPELL_TYPE_ is not recognised (or SPELL_TYPE_PET_BONUS).
		@param $type SPELL_TYPE_*
	*/
	function getSpellCriticalChancePercent($type) {
		switch($type)
		{
			case SPELL_TYPE_ARCANE:
				return  $this->xmlsheet->characterInfo->characterTab->spell->critChance->arcane["percent"];
			case SPELL_TYPE_FIRE:
				return  $this->xmlsheet->characterInfo->characterTab->spell->critChance->fire["percent"];
			case SPELL_TYPE_FROST:
				return  $this->xmlsheet->characterInfo->characterTab->spell->critChance->frost["percent"];
			case SPELL_TYPE_HOLY:
				return  $this->xmlsheet->characterInfo->characterTab->spell->critChance->holy["percent"];
			case SPELL_TYPE_NATURE:
				return  $this->xmlsheet->characterInfo->characterTab->spell->critChance->nature["percent"];
			case SPELL_TYPE_SHADOW:
				return  $this->xmlsheet->characterInfo->characterTab->spell->critChance->shadow["percent"];			default:
				return -1;
		}
	}
	
	/**
		(Integer) Spell penetration value.
	*/
	function getSpellPenetration() {
		return $this->xmlsheet->characterInfo->characterTab->spell->penetration["value"];
	}
	
	/**
		(Array) Mana regeneration.
		Return -> ["casting"], ["noCasting"].
	*/
	function getManaRegen() {
		return array(
			"casting" => $this->xmlsheet->characterInfo->characterTab->spell->manaRegen["casting"],
			"noCasting" => $this->xmlsheet->characterInfo->characterTab->spell->manaRegen["noCasting"]
		);
	}
	
	/**
		(Array) Haste rating.
		Return -> ["hastePercent"], ["hasteRating"].
	*/
	function getSpellHasteRating() {
		return array(
			"hastePercent" => $this->xmlsheet->characterInfo->characterTab->spell->hasteRating["hastePercent"],
			"hasteRating" => $this->xmlsheet->characterInfo->characterTab->spell->hasteRating["hasteRating"]
		);
	}
}

?>